home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 3 / Amiga Tools 3.iso / audio / delitracker_ii / developer / developer.dok next >
Text File  |  1995-03-09  |  35KB  |  828 lines

  1.  
  2.  
  3.                  $VER: Developer.dok V2.07 (24.07.1994)
  4.                    Copyright 1994 by Delirium Softdesign
  5.                       (Peter Kunath and Frank Riffel)
  6.  
  7.                   DeliTracker Development Documentation
  8.  
  9.  
  10.   1.ÜBERBLICK
  11.  
  12.   2.PLAYER
  13.    2.1 Normale Player
  14.    2.2 Custom Module
  15.    2.3 Interrupts
  16.  
  17.   3.GENIES
  18.    3.1 Generic Kind
  19.    3.2 Converter
  20.    3.3 Decruncher
  21.    3.4 NotePlayer
  22.  
  23.   4.TAGS
  24.  
  25.   5.DELITRACKER SUPPORT FUNKTIONEN
  26.  
  27.  
  28.   1.ÜBERBLICK
  29.  
  30.   DeliTracker kann mit externen Programmodulen erweitert werden. Diese
  31.   sehen vom DOS aus betrachtet genauso aus wie normale Objectfiles, mit
  32.   dem Unterschied allerdings, daß sie am Anfang des ersten Hunks eine
  33.   spezielle Struktur besitzen. Wenn DeliTracker ein solches Programmodul
  34.   nachlädt, wertet er diese Struktur aus. Sie besteht aus drei Teilen:
  35.   Einem Longword mit Code, zwei Longwords als Identifier und als letztes
  36.   einem Pointer auf ein Tagarray. Das erste Longword enthält normalerweise
  37.   moveq #-1,d0 gefolgt von einem rts Befehl. Dies soll einen Absturz
  38.   verhindern, wenn ein Player oder Genie irrtümlich vom Benutzer gestartet
  39.   wird. Um ein Programm zu erzeugen, das auch ohne DeliTracker lauffähig
  40.   ist, muß in das erste Longword in einen bra.w geändert werden, der dann
  41.   den eigentlichen Startupcode anspringt. Um die charakteristische Struktur
  42.   zu erzeugen sollte das PLAYERHEADER Macro aus 'deliplayer.i' verwendet
  43.   werden. Es hat zwei Parameter: einen Pointer auf ein Tagarray und
  44.   optional einen Pointer auf den Startupcode.
  45.  
  46.     PLAYERHEADER <tagarray>,[startup]
  47.  
  48.         tagarray        Pointer auf ein Tag Array, das mit TAG_DONE
  49.                         abgeschlossen sein muß.
  50.         startup         Pointer auf einen optionalen Startupcode. Nur
  51.                         notwendig, wenn das Programmodul auch ohne
  52.                         DeliTracker lauffähig sein soll.
  53.                         Bemerkung: Wenn der Startupcode angesprungen
  54.                         wird, muß die gesamte Initialisierung etc. ohne
  55.                         DeliTracker durchgeführt werden. In den meisten
  56.                         Fällen macht die Startup Option wenig Sinn und
  57.                         wird deshalb auch kaum benutzt.
  58.  
  59.   Die Tagliste enthält dabei alle Informationen, die DeliTracker wissen
  60.   muß. Wir verwenden ein Tagarray deshalb, weil es sehr flexibel und leicht
  61.   erweiterbar ist. Zusätzlich können die externen Programmodule noch die
  62.   GlobalStructure sowie die eingebauten Supportfunktionen benutzen. Im
  63.   Moment unterscheidet DeliTracker zwei verschiedene Typen von externen
  64.   Programmodulen:
  65.  
  66.         1) Player, um Module zu identifizieren und zu spielen
  67.  
  68.         2) Genies können viele andere Dinge machen. Unter anderem Module
  69.            konvertieren, Dateien entpacken oder Informationen anzeigen.
  70.  
  71.   Beide Arten können synchron oder asynchron laufen. Unter synchron
  72.   versteht man, daß der Player oder das Genie nicht als eigener Prozess
  73.   läuft. DeliTracker benutzt in diesem Fall echte Funktionsaufrufe (jsr)
  74.   zur Kommunikation. Im asynchronen Modus startet DeliTracker den Player
  75.   oder das Genie als eigenen Prozess und verwendet dann Messages um
  76.   Funktionen der externen Programmodule aufzurufen. Im allgemeinen laufen
  77.   Genies asynchron und Player synchron. Wenn ein Player oder ein Genie
  78.   asynchron läuft, dann muss man es durch Senden eines CTRL-C Signals an
  79.   den Prozeß beenden können. Offensichtlich sind DeliPlayer und DeliGenies
  80.   also sehr ähnlich. Sie werden von DeliTracker auch ziemlich gleich
  81.   verwaltet, wenn auch in zwei verschiedenen Listen. Jedes externe
  82.   Programmodul bei dem ein DTP_CustomPlayer, DTP_Check1 oder DTP_Check2
  83.   Tag benutzt wird, ist ein Player. Der Rest sind Genies.
  84.  
  85.   Wenn eine GUI vorhanden ist, sollten normalerweise folgende Menüpunkte
  86.   zur Verfügung stehen:
  87.  
  88.         Project
  89.                 About      A ?  Kurzinformation über das Programmodul
  90.                 ==============
  91.                 Save Prefs A S  Speichern der aktuellen Einstellungen
  92.                 ==============
  93.                 Hide       A H  GUI verbergen
  94.                 ==============
  95.                 Quit       A Q  Genie beenden (ebenso wie CTRL-C)
  96.  
  97.         Settings
  98.                 Activate   A A  Aktiviert das Fenster beim Öffnen des GUI
  99.                 Popup      A P  Öffnet das GUI nach dem Laden
  100.                 ==============
  101.                 Other settings  Hier können je nach Bedarf weitere
  102.                 ··············  Einstellungen folgen.
  103.  
  104.   Ein paar Anmerkungen:
  105.  
  106.   Bevor man einen DeliPlayer schreibt, sollte man sich die migelieferten
  107.   Beispielsourcen genau durchlesen. Um einen besseren Überblick davon zu
  108.   bekommen, wann und in welcher Reihenfolge DeliTracker die Funktionen des
  109.   Players aufruft, kann man den 'Testplayer.s' Source benutzen. Wenn eine
  110.   Konfigurationsdatei abgespeichert werden kann, sollte sie nicht nach
  111.   ENV:, sondern in das DeliTracker Konfiguartionsverzeichnis abgespeichert
  112.   werden. Der Pfad des Konfiguartionsverzeichnisses kann steht in der ENV-
  113.   Vaiable 'DeliConfig'. Falls diese nicht vorhanden ist, sollte stattdessen
  114.   'PROGDIR:DeliConfig' zum Abspeichern benutzt werden. Ein Player sollte
  115.   außerdem den Zustand der LED (Lowpass-Filter) unbeeinflußt lassen, da im
  116.   Optionfenster eine entsprechende Funktion existiert. Wenn von DeliTracker
  117.   eine Funktion des Players aufgerufen wird (außer bei den Interrupt-
  118.   Funktionen DTP_Interrupt und DTP_NoteSignal), enthält das Register a5
  119.   einen Pointer auf die Globale Struktur (Base). Da DeliTracker vor Aufruf
  120.   einer Routine (außer bei DTP_Interrupt und DTP_NoteSignal) alle Register
  121.   sichert, dürfen diese verändert werden.
  122.  
  123.  
  124.   2.PLAYERS
  125.  
  126.   Es ist relativ einfach, eine Replayroutine an DeliTracker anzupassen.
  127.   Alles was Sie tun müssen ist ein wenig Interfacecode zu schreiben. Dies
  128.   ist im allgemeinen recht einfach, denn DeliTracker stellt ihnen viele
  129.   hilfreiche Routinen zur Verfügung. Um ein neues Soundsystem anzupassen,
  130.   benötigen Sie zum einen den Quellcode oder ein linkbares Objektfile der
  131.   Replayroutine, zum anderen sollten mindestens ca. 5 Module zum Testen der
  132.   Funktionstüchtigkeit des Players vorhanden sein. Ganz am Anfang eines
  133.   Players muß sie charakteristische Struktur stehen. DeliTracker unter-
  134.   scheidet dann zwei Arten von Playern: normale Player und Custom Module.
  135.  
  136.     2.1 Normale Player
  137.  
  138.     Normale Player identifizieren und spielen Module. Sie müssen immer eine
  139.     Check Routine besitzen. Der schematische Aufbau eines normalen Players
  140.     ist folgendermassen:
  141.  
  142.         { Playerheader  }       Kennzeichnet das Object als Player.
  143.         { TagArray      }       Beschreibung, was der Player kann.
  144.         { Interfacecode }       Playername/Registerumsetzung/Checkcode u.ä.
  145.         { Replaycode    }       Eigentlicher Musikabspielcode.
  146.         { evtl. Daten   }       und Daten
  147.  
  148.     Damit der Player die einzelnen Module unterscheiden kann, befindet sich
  149.     in jedem Player eine Erkennungsroutine, die auf ein zugehöriges Modul
  150.     testet und DeliTracker mitteilt, ob der Player dieses Modul spielen
  151.     kann oder nicht. Diese Routine prüft auf Stellen im Modul, die bei allen
  152.     Modulen eines Formats gleich sind. So z.B. auf 'M.K.' bei Offset $438
  153.     in ProTracker-Modulen. Nur auf einige wenige Sprungbefehle zu Prüfen
  154.     reicht im allgemeinen nicht aus, da viele Modulformate mit eingebauter
  155.     Abspielroutine Sprungbefehle am Anfang haben und der Player möglicher-
  156.     weise das falsche Modul erkennen könnte, was in den meisten Fällen zum
  157.     Absturz führt! Deshalb sollte die Check Routine auch eingehend getestet
  158.     werden. Es gibt zwei Typen von Check Funktionen, genau eine davon muß
  159.     der Player verwenden.
  160.  
  161.     a) DTP_Check1: Diese Check Funktion wird aufgerufen, wenn DeliTracker
  162.     1K des Files geladen hat. Der Vorteil ist daß sich auch Player
  163.     realisieren lassen, die das Modul selbst nachladen. Der Nachteil ist,
  164.     daß der Player dann nicht von den Entpackroutinen in DeliTracker
  165.     profitiert. Meistens ist es deshalb schwerer, einen solchen Player zu
  166.     schreiben. Man sollte diesen Typ nur für Härtefälle verwenden, z.B.
  167.     wenn das Modul vom Player selbst geladen werden muß.
  168.  
  169.     b) DTP_Check2: Diese Check Routine wird aufgerufen, wenn das Modul
  170.     geladen und ggf. entpackt ist. Da ein Player mit dieser Check Funktion
  171.     im allgemeinen leichter zu schreiben ist, sollte im Normalfall diese
  172.     Check Routine verwendet werden.
  173.  
  174.     Egal welche Checkfunktion verwendet wird, wenn der Player das Modul
  175.     erkannt hat, muß er in d0.l=0 zurückliefern, wenn nicht d0.l<>0.
  176.  
  177.  
  178.     2.2 Custom Module
  179.  
  180.     Custom Module sind keine Module im herkömmlichen Sinn, sondern
  181.     besondere Player, die ein Modul beinhalten. Sie haben auch keine
  182.     Check Funktion, stattdessen muß der DTP_CustomPlayer Tag verwendet
  183.     werden. Mit diesem Interface kann man auch die ausgefallensten
  184.     Moduleformate an DeliTracker anpassen. Sollten jedoch mehrere Module
  185.     dieses Typs existieren, ist es in jedem Fall ratsam, einen richtigen
  186.     Player zu schreiben.
  187.  
  188.         { Playerheader  }       Kennzeichnet das Object als Player.
  189.         { TagArray      }       Beschreibung, was der Player kann.
  190.         { Interfacecode }       Routinen zur Registerumsetzung u.ä.
  191.         { Replaycode    }       Eigentlicher Musikabspielcode.
  192.         { evtl. Daten   }       und Daten
  193.         { SOUND DATEN   }       Das eigentliche Modul
  194.  
  195.  
  196.     2.3 Interrupts
  197.  
  198.     Hier gibt es eine Einteilung in zwei verschiedene Typen.
  199.  
  200.     a) Player die den DeliTracker Interrupt verwenden
  201.  
  202.      Vorteil:  Der Player ist vom Videomodus unabhängig.
  203.                Besitzt automatisch die Faster/Slower Funktion.
  204.                Kein Aufwand für den Interrupt (Code + Interruptstruktur).
  205.                Automatisch kompatibel zum serial.device.
  206.      Nachteil: Der Interrupt kommt nicht synchron zum VBlank. (Dies führt
  207.                nur in den seltensten Fällen zu Problemen.)
  208.  
  209.     b) Player die ihren eigenen Interrupt erzeugen.
  210.  
  211.      Vorteil:  Es können andere Interruptquellen benutzt werden
  212.                (z.B. AudioIRQ).
  213.      Nachteil: Erhöhter Aufwand, bei VBlank nicht mehr unabhängig vom
  214.                Videomodus.
  215.  
  216.     Wenn ein eigener Timerinterrupt verwendet wird, sollte die CIAB
  217.     (wg. OS2.0) und die entsprechenden Resourcefunktionen verwendet werden.
  218.     Außerdem ist es sehr sinnvoll die Replayroutine nicht direkt im CIA-B
  219.     TimerInterrupt laufen zu lassen, sondern im Timerinterrupt einen
  220.     Soft-Interrupt mittels Cause() zu generieren. In diesem SoftInt kann
  221.     man dann die eigentliche Replayroutine ablaufen lassen. Das hat den
  222.     Vorteil, daß man wesentlich kompatibler zum serial.device ist. Dies
  223.     liegt daran, daß SoftInt eine niedrigere Priorität als der der RBF
  224.     (Read Buffer Full) Interrupt hat d.h. erst wird der serielle Port
  225.     bedient, dann erst die Replayroutine. Es wird davor gewarnt, direkt
  226.     in die Interruptvektoren zu schreiben! Vom Betriebssystem werden dafür
  227.     die Funktionen AddIntServer() und SetIntVector() zur Verfügung
  228.     gestellt.
  229.  
  230.  
  231.   3.GENIES
  232.  
  233.   Die Funktionalität von DeliTracker kann mit Hilfe von Genies auf viele
  234.   verschiedene Arten erweitert werden. Im Moment existieren vier
  235.   grundsätzlich verschiedene Einsatzgebiete für Genies: die Ausgabe von
  236.   Noten (nicht zu verwechseln mit Playern), das Entpacken und Konvertieren
  237.   von Modulen und schließlich das Analysieren des aktuellen Moduls.
  238.  
  239.     3.1 Generic Kind
  240.  
  241.     Diese Art von Genies ist nicht auf spezielle Aufgaben beschrängt. Es
  242.     kann z.B. diverse Informationen über das Modul anzeigen. Natürlich
  243.     darf weder das Modul noch die Globale Struktur zur Gewinnung dieser
  244.     Informationen verändert werden. Überlicherweise benutzt dieser Genie-
  245.     Typ DTP_InitPlay/DTP_EndPlay um zu erfahren, wenn ein neues Modul
  246.     gespielt wird, zusätzlich evtl. auch noch DTP_StartInt/DTP_StopInt.
  247.  
  248.     3.2 Converter
  249.  
  250.     Diese Genies verändern ein Modul. So kann man z.B. das Format des
  251.     Moduls oder seine Länge ändern. Für diese Aufgabe gibt es einen
  252.     speziellen Tag, nämlich DTP_Convert. Er enthält die Adresse der
  253.     Convert-Funktion.
  254.  
  255.     3.3 Decruncher
  256.  
  257.     Diese Art von Genies erweitert die dtg_LoadFile() Funktion von
  258.     DeliTracker. Da sich dieses Interface noch ändern wird, ist es im
  259.     Moment noch nicht dokumentiert.
  260.  
  261.     3.4 Noteplayer
  262.  
  263.     Diese Genies haben die Aufgabe, 'Noten' ggf. zu konvertieren und sie
  264.     auf der jeweiligen Audiohardware auszugeben. Dieses Interface ist zur
  265.     Zeit noch Änderungen unterworfen und deshalb noch nicht dokumentiert.
  266.  
  267.  
  268.   4. TAGS
  269.  
  270.   Außer den SystemTags (TAG_DONE, TAG_IGNORE, TAG_MORE, TAG_SKIP) dürfen
  271.   folgende Tags verwendet werden:
  272.  
  273.   DTP_CustomPlayer (BOOL) - dieser Tag deklariert einen Player als
  274.                 Customplayer.
  275.                 Bei Verwendung dieses Tags sind folgende Tags dann
  276.                 bedeutungslos:  DTP_PlayerVersion
  277.                                 DTP_PlayerName
  278.                                 DTP_Creator
  279.                                 DTP_Check1
  280.                                 DTP_Check2
  281.                                 DTP_ExtLoad
  282.                                 DTP_Config
  283.                                 DTP_UserConfig
  284.  
  285.   DTP_RequestDTVersion (WORD) - damit kann man sicherstellen, daß
  286.                 mindestens eine bestimmte Version von DeliTracker
  287.                 vorhanden ist. Dieser Tag muß angegeben werden, wenn
  288.                 bei den DeliTrackerGlobals neue Funktionspointer
  289.                 hinzugekommen sind und diese vom Player benutzt werden.
  290.                 ti_Data ist dabei die Playerrevision.
  291.  
  292.   DTP_RequestKickVersion (ULONG) - wenn dieser Tag angegeben ist, wird
  293.                 der Player nur noch von von DeliTracker geladen, wenn
  294.                 mindestens die angeforderte Kickstart Version vorhanden
  295.                 ist.
  296.  
  297.   DTP_PlayerVersion (WORD) - Tag, der die Versionsnummer (high word) und
  298.                 die Revisionsnummer (low word) des Players enthält. Bei
  299.                 zwei Playern mit dem gleichen Playernamen wird derjenige
  300.                 mit der größeren Revisionsnummer geladen.
  301.  
  302.   DTP_PlayerName (STRPTR) - ti_Data enthält den Pointer auf den Namen des
  303.                 Players. Dieser String kann zwar beliebig lang sein aber
  304.                 zur Zeit werden nur die ersten 24 Zeichen angezeigt. Dieser
  305.                 Tag muß existieren!
  306.  
  307.   DTP_Creator (STRPTR) - Pointer auf den Namen des Autors. Dieser wird im
  308.                 Playerfenster im Playerinfofeld angezeigt. Der String
  309.                 kann $A als Zeilenumbruch enthalten.
  310.  
  311.   DTP_Check1 (FPTR) - Pointer auf eine Modulerkennungsroutine, die
  312.                 aufgerufen wird, wenn 1024 Bytes des Moduls geladen sind.
  313.                 Wird das Modul erkannt, liefert sie d0=0, ansonsten d0<>0.
  314.  
  315.   DTP_Check2 (FPTR) - Pointer auf eine Modulerkennungsroutine, die
  316.                 aufgerufen wird, wenn das komplette Modul geladen und evtl.
  317.                 entpackt ist. Wird das Modul erkannt, liefert sie d0=0,
  318.                 ansonsten d0<>0.
  319.  
  320.   DTP_ExtLoad (FPTR) - Pointer auf eine optionale Laderoutine für Module.
  321.                 Ist kein Fehler aufgetreten, wird d0=0 zurückgegeben, sonst
  322.                 d0<>0. Hinweis: Achten Sie darauf, daß im Fehlerfall alle
  323.                 allocierten Ressourcen (Memory, Locks, ...) wieder
  324.                 freigegeben werden, da dann keine weiteren Playerfunktionen
  325.                 mehr angesprungen werden.
  326.  
  327.   DTP_Interrupt (FPTR) - Pointer auf eine Interruptroutine, die mittels
  328.                 eines Timerinterrupts standardmäßig alle 1/50 sec
  329.                 aufgerufen wird. Dies ist die Standardmethode, um mit der
  330.                 richtigen Abspielgeschwindigkeit im PAL/NTSC/Productivity
  331.                 Videomodus zu spielen. Wenn keine DTP_Faster/DTP_Slower
  332.                 Tags angegeben sind, übernimmt DeliTracker dies durch
  333.                 Verändern der Interruptfrequenz. Dieser Tag kann auch nicht
  334.                 existieren, dann müssen aber DTP_StartInt/DTP_StopInt
  335.                 vorhanden sein !
  336.  
  337.   DTP_Stop (FPTR) - Pointer auf eine optionale Stoproutine. Wenn dieser Tag
  338.                 nicht vorhanden ist, verfährt DeliTracker folgendermaßen:
  339.                         Interrupt stoppen (DTP_StopInt)
  340.                         Sound Cleanup (DTP_EndSnd)
  341.                         Song initialisieren (DTP_InitSnd)
  342.                 Ansonsten hat diese Routine die Aufgabe, einen evtl.
  343.                 spielenden Song anzuhalten und so zu initialisieren, daß
  344.                 dieser beim nächsten Starten des Interrupts von Anfang an
  345.                 zu spielen beginnt.
  346.  
  347.   DTP_Config (FPTR) - Pointer auf eine optionale Initialisierungsroutine.
  348.                 Diese wird nur einmal unmittelbar nach dem Laden des
  349.                 Players aufgerufen. Mögliche Anwendungen: Laden einer
  350.                 playerspezifischen Konfigurationsdatei. Ist kein Fehler
  351.                 aufgetreten, muss d0=0 zurückgegeben werden, sonst
  352.                 d0<>0. Hinweis: Im Fehlerfall wird der Player von
  353.                 DeliTracker wieder entfernt!
  354.  
  355.   DTP_UserConfig (FPTR) - Pointer auf eine optionale Initialisierungs-
  356.                 routine. Diese wird nur dann aufgerufen, wenn der User den
  357.                 Player im Setupfenster anwählt und das 'Config' Gadget
  358.                 drückt. Mögliche Anwendungen: Öffnen eines Fensters zum
  359.                 Setzen weiterer Optionen wie z.B. Instrumentenpfad und
  360.                 Abspeichern einer playerspezifischen Konfigurationsdatei.
  361.  
  362.   DTP_SubSongRange (FPTR) - Überholt, bitte DTP_NewSubSongRange benützen!
  363.                 Dieser Tag sollte angegeben werden, wenn der Player
  364.                 MultiModule unterstützt. ti_Data zeigt dabei auf eine
  365.                 Routine, die als Returnwert in d0 die minimale und
  366.                 in d1 die maximale Subsongnummer zurückgeben muß.
  367.                 Hinweis: Wenn möglich sollte dieser Tag (evtl. zusammen
  368.                 mit DTP_SubSongTest) anstelle von DTP_NextSong/DTP_PrevSong
  369.                 verwendet werden.
  370.  
  371.   DTP_InitPlayer (FPTR) - Pointer auf eine optionale Initialsierungs-
  372.                 routine, die aufgerufen wird, wenn ein Modul erfolgreich
  373.                 geladen wurde. Tritt kein Fehler auf, liefert sie d0=0,
  374.                 ansonsten d0<>0. Hier muß die Allocation der Audiokanäle
  375.                 stattfinden! (DeliTracker stellt dafür eine eigene Routine
  376.                 zur Verfügung) Falls der Player Multi-Module unterstützt,
  377.                 muß hier dtg_SndNum(a5) auf die erste Subsongnummer gesetzt
  378.                 werden. Falls eine Routine für DTP_SubSongRange existiert,
  379.                 macht DeliTracker das automatisch (d.h. die Initialisierung
  380.                 von dtg_SndNum(a5) kann weggelassen werden).
  381.  
  382.   DTP_EndPlayer (FPTR) - Pointer auf eine optionale Cleanuproutine, die
  383.                 aufgerufen wird, wenn das Modul aus dem Speicher entfernt
  384.                 wird. Hier muß die Freigabe der Audiokanäle stattfinden!
  385.                 (DeliTracker stellt dafür eine eigene Routine zur
  386.                 Verfügung)
  387.  
  388.   DTP_InitSound (FPTR) - Pointer auf eine optionale Initialsierungsroutine.
  389.                 Diese muß das Modul initialisieren, so daß beim Starten des
  390.                 Interrupts der Song von Anfang an zu spielen beginnt.
  391.  
  392.   DTP_EndSound (FPTR) - Pointer auf eine optionale Cleanuproutine. Diese
  393.                 kann z.B. die Lautstärkeregister und die Audio-DMA
  394.                 rücksetzen.
  395.  
  396.   DTP_StartInt (FPTR) - Pointer auf eine Initialsierungsroutine, die
  397.                 existieren muß, wenn DTP_Interrupt nicht vorhanden ist.
  398.                 In diesem Fall muß hier der Sound gestartet werden.
  399.  
  400.   DTP_StopInt (FPTR) - Pointer auf eine Cleanuproutine, die existieren muß,
  401.                 wenn DTP_Interrupt nicht vorhanden ist. In diesem Fall muß
  402.                 hier der Sound gestoppt werden.
  403.  
  404.   DTP_Volume (FPTR) - Pointer auf eine Funktion, welche die Lautstärke neu
  405.                 setzt. Die Funktion wird aufgerufen, wenn die Volume neu
  406.                 gesetzt wird (Slider, ARexx) und beim Initialisieren des
  407.                 Moduls vor DTP_InitSnd. Die Mastervolume steht in
  408.                 dtg_SndVol(a5). Die Mastervolume ist dabei der maximale
  409.                 Volumewert. Die effektive Volume errechnet sich also
  410.                 durch: VOL_eff = (( dtg_Volume(a5) * modulevolume )>>6)
  411.                 Näheres siehe Beispielsourcen.
  412.  
  413.   DTP_Balance (FPTR) - Pointer auf eine Funktion, welche die Balance neu
  414.                 setzt. Die Funktion wird aufgerufen, wenn die Balance neu
  415.                 gesetzt wird (Slider, ARexx) und beim Initialisieren des
  416.                 Moduls vor DTP_InitSnd. Die Balance für die linken Kanäle
  417.                 steht in dtg_SndLBal(a5), für die rechten Kanäle in
  418.                 dtg_SndRBal(a5). Hinweis: Alle Player die Balance unterstützen
  419.                 können auch Volume! Man verwendet dann die gleiche Routine
  420.                 zum Setzen der Volume&Balance. Die linke Volume errechnet
  421.                 sich wie folgt: (( dtg_Volume(a5) * dtg_SndLBal(a5) )>>6)
  422.                 Entsprechendes gilt für rechts.
  423.  
  424.   DTP_Faster (FPTR) - Pointer auf eine Funktion, die den Abspielvorgang
  425.                 beschleunigt.
  426.  
  427.   DTP_Slower (FPTR) - Pointer auf eine Funktion, die den Abspielvorgang
  428.                 verlangsamt.
  429.  
  430.   DTP_NextPatt (FPTR) - Pointer auf eine Funktion, die den Patternzeiger
  431.                 um eins erhöht.
  432.  
  433.   DTP_PrevPatt (FPTR) - Pointer auf eine Funktion, die den Patternzeiger
  434.                 um eins erniedrigt.
  435.  
  436.   DTP_NextSong (FPTR) - Pointer auf eine Funktion, die Subsongnummer auf
  437.                 den nächsten Subsong setzt und diesen spielt.
  438.                 (Falls vorhanden)
  439.  
  440.   DTP_PrevSong (FPTR) - Pointer auf eine Funktion, die Subsongnummer auf
  441.                 den vorhergehenden Subsong setzt und diesen spielt.
  442.                 (Falls vorhanden)
  443.  
  444.   ;--- tags in revision 14 or higher (distributed as Release 1.35) ---
  445.  
  446.   DTP_SubSongTest (FPTR) - Dieser Tag wird nur ausgewertet, wenn schon der
  447.                 Tag DTP_SubSongRange angegeben wurde. ti_Data zeigt dabei
  448.                 auf eine Routine, die als Returnwert in d0 einen Boolschen
  449.                 Wert zurückliefert. Dieser gibt an, ob der SubSong mit
  450.                 Nummer dtg_SndNum(a5) gültig ist (d0=0) oder nicht (d0<>0).
  451.                 Dieser Tag ist nur bei den Playern nötig, bei denen nicht
  452.                 jeder SubSong (innerhalb der durch DTP_SubSongRange
  453.                 festgelegten Grenzen) benutzt ist.
  454.  
  455.   ;--- tags in revision 16 or higher (distributed as Release 2.00) ---
  456.  
  457.   DTP_NewSubSongRange (APTR) - erweiterter Ersatz für DTP_SubSongRange.
  458.                 Dieser Tag sollte angegeben werden, wenn der Player
  459.                 MultiModule unterstützt. ti_Data zeigt dabei auf ein
  460.                 Array mit drei WORDs: Das erste Word enthält die Nummer
  461.                 des Subsongs, der als erstes gespielt werden soll. Das
  462.                 zweite enthält die minimale und das dritte die maximale
  463.                 Subsong Nummer. In den meisten Fällen ist das erste und
  464.                 das zweite WORD identisch.
  465.  
  466.   DTP_DeliBase (APTR) - die Adresse eines Pointers, wo DeliTracker einen
  467.                 Pointer auf die DeliGlobals ablegt.
  468.  
  469.   DTP_Flags (ULONG) - enthält verschiedene Flags.
  470.                 Derzeit sind folgende Flags definiert:
  471.                 PLYF_CUSTOM     - der Player ist ein Customplayer
  472.                 PLYF_SONGEND    - dieser Player unterstützt Songend
  473.  
  474.   DTP_CheckLen (ULONG) - Länge des Check Codes. Dieser Tag darf nur benutzt
  475.                 werden, wenn der Checkcode PC-relativ und reentrant ist!
  476.                 Wenn der Tag benutzt wird, lagert DeliTracker den Player in
  477.                 LowMem-Situationen aus.
  478.  
  479.   DTP_Description (APTR) - Pointer auf einen String mit einer Beschreibung,
  480.                 was der Player bzw. das Genie tut und welche besonderen
  481.                 Fähigkeiten es hat. Dieser String kann $A als Zeilenumbruch
  482.                 enthalten.
  483.  
  484.   DTP_Decrunch (FPTR) - private, still under development!
  485.  
  486.   DTP_Convert (FPTR) - Pointer auf eine Routine zum Konvertieren eines
  487.                 Moduls. Diese Routine wird aufgerufen, wenn das Modul
  488.                 geladen und ggf. entpackt ist. Sie dient dazu, das Modul
  489.                 in ein neues Format umzukonvertieren. Die Konvertier-
  490.                 Routine funktioniert üblicherweise folgendermassen:
  491.                         1) Ausgangs-Format erkennen
  492.                         2) Speicher für Ziel-Format mit dtg_AllocListData()
  493.                            belegen
  494.                         3) Das Modul vom Ausgangsformat ins Zielformat
  495.                            konverieren
  496.                 Diese Routine muß NULL zurückliefern, wenn das Modul
  497.                 erfolgreich konvertiert wurde (success), ansonsten -1
  498.                 (error). Auf gar keinen Fall darf das Ausgangs-Modul von
  499.                 der Konvertier-Funktion verändert werden!
  500.                 Bemerkung: für temporäre Speicher-Allocationen sollte man
  501.                 die entsprechenden Exec-Funktionen benutzen, der Speicher
  502.                 für das Ziel-Modul muß aber in jedem Fall mit der Support
  503.                 Funktion dtg_AllocListData() belegt werden!
  504.  
  505.   DTP_NotePlayer (APTR) - private, still under development!
  506.  
  507.   DTP_NoteStruct (APTR) - private, still under development!
  508.  
  509.   DTP_NoteInfo (APTR) - private, still under development!
  510.  
  511.   DTP_NoteSignal (FPTR) - private, still under development!
  512.  
  513.   DTP_Process (FPTR) - Pointer auf einen Code, der als Prozess gestartet
  514.                 werden soll. Wenn dieser Tag verwendet wird, startet
  515.                 DeliTracker den Player bzw. das Genie als eigenen Prozess.
  516.  
  517.   DTP_Priority (BYTE) -  Priorität des zu startenden Prozesses. Nur in
  518.                 Verbindung mit DTP_Process sinnvoll.
  519.  
  520.   DTP_StackSize (ULONG) - Stack-Größe des zu startenden Prozesses. Nur in
  521.                 Verbindung mit DTP_Process sinnvoll.
  522.  
  523.   DTP_MsgPort (APTR) - Adresse eines Pointer, wo DeliTracker die Adresse
  524.                 des Ports ablegt, an den dann die Messages geschickt
  525.                 werden. Nur in Verbindung mit DTP_Process sinnvoll.
  526.  
  527.   DTP_Appear (FPTR) - Pointer auf eine Routine die die GUI des Players bzw.
  528.                 Genies öffnet/aktiviert. Als Returnwert muß der alte
  529.                 Windowzustand (<>0 wenn das Fenster auf war, ansonsten 0)
  530.                 zurückgeliefert werden. Bemerkung: Stellen Sie sicher, daß
  531.                 die GUI auf dem richtigen Screen geöffnet wird! (benützen
  532.                 Sie dazu die dtg_LockPubScreen() und dtg_UnLockPubScreen()
  533.                 Funktionen).
  534.  
  535.   DTP_Disappear (FPTR) - Pointer auf eine Routine, die die GUI schliesst.
  536.                 Diese Routine muss den alten Windowzustand (<>0 wenn das
  537.                 Fenster auf war, ansonsten 0) zurückgeliefern.
  538.  
  539.   DTP_ModuleName (APTR) - Adresse eines Pointers, der auf den tatsächlichen
  540.                 Namen des Moduls zeigt (dieser String muß mit NULL
  541.                 abgeschlossen sein). Dieser Tag ist nur für Player sinnvoll
  542.                 und wird nach InitPlay() ausgewertet.
  543.  
  544.   DTP_FormatName (APTR) - Adresse eines Pointers, der auf den Namen des
  545.                 urspünglichen Modulformats zeigt (dieser String muß mit
  546.                 NULL abgeschlossen sein). Dieser Tag ist nur für Genies
  547.                 sinnvoll und wird nach der Convert() Funktion ausgewertet.
  548.  
  549.  
  550.   5.DELITRACKER SUPPORT FUNKTIONEN
  551.  
  552.   DeliTracker stellt zur Erleichterung der Playeranpassung einige
  553.   Funktionen zur Verfügung. Eine Funktion wird wie folgt aufgerufen:
  554.  
  555.         move.l  dtg_XXX(a5),a0
  556.         jsr     (a0)
  557.  
  558.   Alle folgenden Funktionen außer dtg_SongEnd, dtg_SetTimer und
  559.   dtp_NotePlayer verwenden d0/d1/a0/a1 als Scratchregister. In a5 muß bei
  560.   allen Aufrufen (außer bei dtg_SongEnd, dtg_SetTimer und dtp_NotePlayer)
  561.   der Pointer auf die Base stehen. Derzeit existieren folgende Funktionen:
  562.  
  563.   dtg_GetListData
  564.  
  565.         SYNOPSIS
  566.                 memory size = dtg_GetListData(number)
  567.                 a0     d0                     d0.l
  568.  
  569.         FUNCTION
  570.                 Liefert Adresse und Länge eines mit LoadFile() geladenen
  571.                 Files.
  572.  
  573.         INPUTS
  574.                 number - Nummer eines Files beginnend mit 0 für das vom
  575.                          User selektierte File.
  576.  
  577.         RESULT
  578.                 memory - ein Pointer auf die Startadresse des Files im
  579.                          Speicher oder NULL im Fehlerfall.
  580.                 size - Länge des Files in Bytes bzw. 0 im Fehlerfall.
  581.  
  582.  
  583.   dtg_LoadFile
  584.  
  585.         SYNOPSIS
  586.                 success = dtg_LoadFile(name)
  587.  
  588.         FUNCTION
  589.                 Lädt und entpackt ggf. das angegebene File ins Chip-
  590.                 Memory. (Hinweis: diese Funktion ergänzt automatisch,
  591.                 falls das File mit dem angegebenen Namen nicht geöffnet
  592.                 werden konnte '.pp','.im' und '.xpk')
  593.  
  594.         INPUTS
  595.                 name - der Filename steht in einem internen Buffer (seine
  596.                        Adresse steht in dtg_PathArray)
  597.  
  598.         RESULT
  599.                 success - alles ok d0.l=0, sonst d0.l<>0.
  600.  
  601.  
  602.   dtg_CopyDir
  603.  
  604.         SYNOPSIS
  605.                 dtg_CopyDir()
  606.  
  607.         FUNCTION
  608.                 Kopiert das Directory des von User angewählten Files an das
  609.                 Ende des Strings, auf den dtg_PathArray(a5) zeigt.
  610.  
  611.  
  612.   dtg_CopyFile
  613.  
  614.         SYNOPSIS
  615.                 dtg_CopyFile()
  616.  
  617.         FUNCTION
  618.                 Kopiert den Filenamen des von User angewählten Files an das
  619.                 Ende des Strings, auf den dtg_PathArray(a5) zeigt.
  620.  
  621.  
  622.   dtg_CopyString
  623.  
  624.         SYNOPSIS
  625.                 dtg_CopyString(string)
  626.                                a0
  627.  
  628.         FUNCTION
  629.                 Kopiert den String, auf den das Register a0 zeigt, an das
  630.                 Ende des Strings, auf den dtg_PathArray(a5) zeigt.
  631.  
  632.         INPUTS
  633.                 string - der Pointer auf den anzuhängenden String steht
  634.                          in a0
  635.  
  636.  
  637.   dtg_AudioAlloc
  638.  
  639.         SYNOPSIS
  640.                 success = dtg_AudioAlloc()
  641.  
  642.         FUNCTION
  643.                 Belegt alle Audiokanäle.
  644.  
  645.         RESULT
  646.                 success - alles ok d0.l=0, sonst d0.l<>0.
  647.  
  648.  
  649.   dtg_AudioFree
  650.  
  651.         SYNOPSIS
  652.                 dtg_AudioFree()
  653.  
  654.         FUNCTION
  655.                 Gibt die mit dtg_AudioAlloc belegten Audiokanäle wieder
  656.                 frei.
  657.  
  658.  
  659.   dtg_StartInt
  660.  
  661.         SYNOPSIS
  662.                 dtg_StartInt()
  663.  
  664.         FUNCTION
  665.                 Startet den Soundinterrupt. (Falls er nicht schon läuft.)
  666.                 Falls DTP_Interrupt existiert, startet DeliTracker einen
  667.                 Timerinterrupt, ansonsten wird DTP_StartInt aufgerufen.
  668.  
  669.  
  670.   dtg_StopInt
  671.  
  672.         SYNOPSIS
  673.                 dtg_StopInt()
  674.  
  675.         FUNCTION
  676.                 Stoppt den Soundinterrupt. (Falls er nicht schon angehalten
  677.                 ist.) Falls DTP_Interrupt existiert, stoppt DeliTracker
  678.                 seinen Timerinterrupt, ansonsten wird DTP_StopInt
  679.                 aufgerufen.
  680.  
  681.  
  682.   dtg_SongEnd
  683.  
  684.         SYNOPSIS
  685.                 dtg_SongEnd()
  686.  
  687.         FUNCTION
  688.                 Signalisiert DeliTracker, daß das Modul einmal komplett
  689.                 gespielt wurde. Diese Funktion verändert keine Register
  690.                 und darf auch von Interrupts aufgerufen werden.
  691.  
  692.  
  693.   dtg_CutSuffix
  694.  
  695.         SYNOPSIS
  696.                 dtg_CutSuffix()
  697.  
  698.         FUNCTION
  699.                 Entfernt am Ende des Strings, auf den dtg_PathArray(a5)
  700.                 zeigt ggf. die Endung '.pp', '.im' oder '.xpk'
  701.  
  702.  
  703.   ;------ extensions in revision 14 (distributed as Release 1.34)
  704.  
  705.   dtg_SetTimer
  706.  
  707.         SYNOPSIS
  708.                 dtg_SetTimer()
  709.  
  710.         FUNCTION
  711.                 Programmiert den CIA-Timer mit dem Wert, der sich in
  712.                 dtg_Timer(a5) befindet. Diese Funktion verändert keine
  713.                 Register und darf auch von Interrupts aufgerufen werden.
  714.  
  715.  
  716.   ;------ extensions in revision 15 (distributed as Release 1.37)
  717.  
  718.   dtg_WaitAudioDMA
  719.  
  720.         SYNOPSIS
  721.                 dtg_WaitAudioDMA()
  722.  
  723.         FUNCTION
  724.                 Diese Funktion wartet eine bestimmte Zeit lang. Die
  725.                 Zeitspanne sollte für die Audio Hardware normalerweise
  726.                 groß genug sein, um neue Werte zu laden. Dieser Aufruf ist
  727.                 nur erlaubt, wenn der interne Timer-Interrupt benutzt wird.
  728.                 Er kann anstelle der üblichen dbra oder Rasterline
  729.                 Warteschleifen benutzt werden. Diese Funktion verändert
  730.                 keine Register.
  731.  
  732.         BUGS
  733.                 Wenn der Player auch Periods unterstützt, die viel größer
  734.                 als 1000 sind, wird evtl. nicht lange genug gewartet.
  735.  
  736.  
  737.   ;------ extensions in revision 16 (distributed as release 2.00)
  738.  
  739.   dtg_LockScreen
  740.  
  741.         SYNOPSIS
  742.                 screen = dtg_LockScreen()
  743.                 (d0)
  744.  
  745.         FUNCTION
  746.                 Lockt den Screen auf dem DeliTracker läuft (ist immer
  747.                 ein Pubscreen).
  748.  
  749.         RESULT
  750.                 Pointer auf den Screen in d0 oder NULL im Fehlerfall.
  751.  
  752.  
  753.   dtg_UnlockScreen
  754.  
  755.         SYNOPSIS
  756.                 dtg_UnlockScreen()
  757.  
  758.         FUNCTION
  759.                 Diese Function unlockt den Screen, auf dem DeliTracker
  760.                 läuft. Hinweis: diese Funktion keinesfalls öfters aufrufen
  761.                 als dtg_LockScreen()!).
  762.  
  763.  
  764.   dtg_NotePlayer
  765.  
  766.         SYNOPSIS
  767.                 dtg_NotePlayer()
  768.  
  769.  
  770.         FUNCTION
  771.                 Dieser Aufruf spielt die Noten, die in der aktuellen
  772.                 NoteStruct Struktur angegeben sind. Die Funktion darf
  773.                 nicht aufgerufen werden, wenn der aktive Player keine
  774.                 NotePlayer Structur hat.
  775.                 Hinweis: Dieser Aufruf sichert alle Register und darf
  776.                 sogar von Interrupts aufgerufen werden, solange das
  777.                 Interrupt Level 4 oder kleiner ist.
  778.  
  779.         INPUTS
  780.                 aktuelle NoteStruct.
  781.  
  782.  
  783.   dtg_AllocListData
  784.  
  785.         SYNOPSIS
  786.                 memory = dtg_AllocListData(byteSize,Flags)
  787.                 (d0)                      (d0.l) (d1.l)
  788.  
  789.  
  790.         FUNCTION
  791.                 Dies ist die Funktion, um Modul-spezifischen Speicher von
  792.                 Playern oder Genies aus zu belegen. Es gibt die Möglichkeit
  793.                 anzugeben, ob die Allocation im Chipmem oder Publicmem
  794.                 gemacht werden soll. Wenn die Allocation erfolgreich war,
  795.                 merkt DeliTracker sich den Memblock und man kann mit der
  796.                 Funktion dtg_GetListData() die Adresse und die Größe des
  797.                 Blocks erfahren.
  798.  
  799.  
  800.         INPUTS
  801.                 byteSize - Größe des gewünschten Blocks in Bytes.
  802.  
  803.                 Flags - die Flags werden an AllocMem() weitergereicht.
  804.  
  805.         RESULT
  806.                 Ein Pointer auf den allocierten Memoryblock wird in d0
  807.                 zurückgeliefert. Wenn nicht genug freier Speicher vorhanden
  808.                 ist, um die Anforderung zu erfüllen, wird Null
  809.                 zurückgegeben. Der Pointer muß auf jeden Fall getestet
  810.                 werden und darf nur benutzt werden, wenn er ungleich Null
  811.                 ist.
  812.  
  813.  
  814.   dtg_FreeListData
  815.  
  816.         SYNOPSIS
  817.                 dtg_FreeListData(memoryBlock)
  818.                                   (a1)
  819.  
  820.         FUNCTION
  821.                 Gibt einen Speicherblock frei, der mit AllocListData(),
  822.                 allociert wurde.
  823.  
  824.         INPUTS
  825.                 memoryBlock - Pointer auf den Speicherblock, darf auch
  826.                               NULL sein.
  827.  
  828.